Python socket 客户端和服务器端 |
您所在的位置:网站首页 › python socket connect › Python socket 客户端和服务器端 |
connection, address = socket.accept() 调 用accept方法时,socket会时入“waiting”状态。客户请求连接时,方法建立连接并返回服务器。accept方法返回一个含有两个元素的 元组(connection,address)。第一个元素connection是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。第五步是处理阶段,服务器和客户端通过send和recv方法通信(传输 数据)。服务器调用send,并采用字符串形式向客户发送信息。send方法返回已发送的字符个数。服务器使用recv方法从客户接收信息。调用recv 时,服务器必须指定一个整数,它对应于可通过本次方法调用来接收的最大数据量。recv方法在接收数据时会进入“blocked”状态,最后返回一个字符 串,用它表示收到的数据。如果发送的数据量超过了recv所允许的,数据会被截短。多余的数据将缓冲于接收端。以后调用recv时,多余的数据会从缓冲区 删除(以及自上次调用recv以来,客户可能发送的其它任何数据)。传输结束,服务器调用socket的close方法关闭连接。python编写client的步骤: 举例: 服务端: #socket server端#获取socket构造及常量from socket import *#''代表服务器为localhostmyHost = ''#在一个非保留端口号上进行监听myPort = 50007 #设置一个TCP socket对象sockobj = socket(AF_INET, SOCK_STREAM)#绑定它至端口号sockobj.bind((myHost, myPort))#监听,允许5个连结sockobj.listen(5) #直到进程结束时才结束循环while True: #等待下一个客户端连结 connection, address = sockobj.accept( ) #连结是一个新的socket print 'Server connected by', address while True: #读取客户端套接字的下一行 data = connection.recv(1024) #如果没有数量的话,那么跳出循环 if not data: break #发送一个回复至客户端 connection.send('Echo=>' + data) #当socket关闭时eof connection.close( ) 客户端: import sysfrom socket import *serverHost = 'localhost'serverPort = 50007 #发送至服务端的默认文本message = ['Hello network world']#如果参数大于1的话,连结的服务端为第一个参数if len(sys.argv) > 1: serverHost = sys.argv[1] #如果参数大于2的话,连结的文字为第二个参数 if len(sys.argv) > 2: message = sys.argv[2:] #建立一个tcp/ip套接字对象sockobj = socket(AF_INET, SOCK_STREAM)#连结至服务器及端口sockobj.connect((serverHost, serverPort)) for line in message: #经过套按字发送line至服务端 sockobj.send(line) #从服务端接收到的数据,上限为1k data = sockobj.recv(1024) #确认他是引用的,是'x' print 'Client received:', repr(data) #关闭套接字sockobj.close( ) 参考: http://blog.sina.com.cn/s/blog_523491650100hikg.html 创建一个socket客户端 输出: Socket createdip address of www.baidu.com is 115.239.210.26Msg Send successfully!HTTP/1.1 200 OKDate: Fri, 21 Feb 2014 05:32:29 GMTContent-Type: text/htmlTransfer-Encoding: chunkedConnection: Keep-AliveVary: Accept-EncodingSet-Cookie: BAIDUID=0D5536687056DF9F5C088AFBE27E42B7:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.comSet-Cookie: BDSVRTM=7; path=/Set-Cookie: H_PS_PSSID=4850_1432_5186_5198_4261_5260_4760_5208; path=/; domain=.baidu.comP3P: CP=" OTI DSP COR IVA OUR IND COM "Expires: Fri, 21 Feb 2014 05:32:29 GMTCache-Control: privateServer: BWS/1.1BDPAGETYPE: 1BDQID: 0x95f7c521930a6c8eBDUSERID: 0 为什么没有输出全部数据呢?看下面的函数: socket.recv(bufsize[, flags]) Receive data from the socket. The return value is a string representing the data received. The maximum amount of data to be received at once is specified by bufsize. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero. Note For best match with hardware and network realities, the value of bufsize should be a relatively small power of 2, for example, 4096. 输出不完整。一些数据被漏掉。在TCP/IP协议下上面的情况会发生。在这个协议,数据以块进行传输。例如一个网页是500kb,但是最大快只有64kb。因此传输网页时,一次只传输了一部分而不是全部。 这就是问题产生的原因。recv函数能够等待直到收到所有的数据,但是对此,它必须知道整个要传输数据的大小。s.recv(4096 , socket.MSG_WAITALL) 会等待直到得到整个4096 bytes。现在如果实际响应的大小小于这个尺寸,函数会被阻塞一段时间,直到它返回。这不是我们所期待的。 解决: 解决方法是保持查询数据直到一个适当的超时发生,下面的例子中,我们就是这么做的: 步骤是: 1.保证socket非阻塞。对此,socket不会等待,如果在recv调用没有数据。它会继续,如果没有数据可用。 2.按下面方式循环:保持调用recv,直到一个超时发生或recv完成。 现在这是一个简单的方法来证明recv函数在实际的应用中该如何工作。同样的函数能够进一步开发,然后变得更复杂,根据工作的协议,例如HTTP。 创建一个socket服务器端 以上例子参考于: http://www.oschina.net/question/12_76126?sort=default&p=2#answers |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |